package com.ys.chatserver.http.logic;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.eva.epc.common.util.CommonUtils;
import com.eva.framework.Processor;
import com.eva.framework.dto.SysActionConst;
import com.eva.framework.utils.EndsExceptionFactory;
import com.google.gson.Gson;
import com.ys.chatserver.common.dto.cnst.RetResult;
import com.ys.chatserver.common.dto.cnst.ShortUuidUtil;
import com.ys.chatserver.http.logic.dto.JobDispatchConst;
import com.ys.chatserver.http.logic.dto.StructureInfoVO;
import com.ys.chatserver.tool.EmptyUtils;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Vector;
import java.util.stream.Collectors;

public class StructureInfoProccessor implements SysActionConst, Processor {

    private Gson gson = new Gson();

    @Override
    public Object process(int job_dispatch_id, int action_id, Object newData, Object oldData, User user) throws Exception {
        Object ret = null;
        String newDataJSON = (String) newData;

        switch (job_dispatch_id) {
            case JobDispatchConst.LOGIC_GROUP_STRUCTURE:
                ret = maintainMgrGpsJobDispatcher(action_id, newDataJSON, oldData, user);
                break;
            default:
                throw EndsExceptionFactory.INVALID_JOB_DISPATCHER_ID(job_dispatch_id);
        }
        return ret;
    }

    private Object maintainMgrGpsJobDispatcher(int actionId, String newDataJSON, Object oldData, User user) throws Exception {

        switch (actionId) {
            case ACTION_ADD_STRUCTURE: {//添加组织
                JSONObject jsonObj = JSON.parseObject(newDataJSON);
                //创建者名称
                String creatorName = jsonObj.getString("creatorName");
                //创建组织名称
                String structureName = jsonObj.getString("structureName");
                if (EmptyUtils.isEmpty(structureName)) {
                    return gson.toJson(RetResult.failResult("参数错误!"));
                }
                List<StructureInfoVO> list = queryStructureByCreatorId(user.getUserId());
                if (!list.isEmpty()) {
                    return gson.toJson(RetResult.failResult("添加失败!您已创建了一个组织!"));
                }

                List<StructureInfoVO> vos = new ArrayList<>();
                Vector<Vector<?>> vector = getUserStrure(user.getUserId());
                String structuresNo = ShortUuidUtil.getShortUuid();
                StructureInfoVO vo = new StructureInfoVO();
                vo.setStructureNo(structuresNo);
                vo.setStructureName(structureName);
                vo.setStructureType(0);
                vo.setCreatorName(creatorName);
                vo.setCreatorId(user.getUserId());
                if (vector.isEmpty()) { //没有在任何组织下
                    vo.setStructureLevel(structuresNo);
                    vo.setParentNo(structuresNo);
                    vo.setRootNo(structuresNo);
                    vos.add(vo);
                } else {
                    String parentNo = (String) vector.get(0).get(0);
                    String rootNo = (String) vector.get(0).get(1);
                    if (Boolean.TRUE.equals(exitStructureName(parentNo, structureName))) {
                        return gson.toJson(RetResult.failResult("该组织下名称['" + structureName + "']已存在,请勿重复创建!"));
                    }
                    String structureLevel = (String) vector.get(0).get(2);
                    vo.setStructureLevel(structureLevel + ":" + structuresNo);
                    vo.setParentNo(parentNo);
                    vo.setRootNo(rootNo);
                    vos.add(vo);
                }
                return addStructures(vos);
            }
            case ACTION_UPDATE_STRUCTURE: { //修改组织信息
                JSONObject jsonObj = JSON.parseObject(newDataJSON);
                String structureNo = jsonObj.getString("structureNo");
                String structureName = jsonObj.getString("structureName");
                if (EmptyUtils.isEmpty(structureNo) || EmptyUtils.isEmpty(structureName)) {
                    return gson.toJson(RetResult.failResult("参数错误!"));
                }
                return updateStructuresByNo(structureNo, user.getUserId(), structureName);
            }
            case ACTION_DELETE_STRUCTURE: { //删除组织
                JSONObject jsonObj = JSON.parseObject(newDataJSON);
                String structureNo = jsonObj.getString("structureNo");
                String creatorId = user.getUserId();
                if (EmptyUtils.isEmpty(structureNo)) {
                    gson.toJson(RetResult.failResult("参数错误|"));
                }
                return deleteStructuresByNo(structureNo, creatorId);
            }
            case ACTION_QUERY_STRUCTURE: { //查询组织列表
                JSONObject jsonObj = JSON.parseObject(newDataJSON);
                String structureNo = jsonObj.getString("structureNo");
                if (EmptyUtils.isEmpty(newDataJSON)) {
                    return gson.toJson(RetResult.failResult("组织编号不能为空！"));
                }
                String creatorId = user.getUserId();
                if (isManager(creatorId) == 1) {
                    return gson.toJson(RetResult.failResult("暂无权限"));
                }
                return queryByNoAndId(structureNo, creatorId);
            }
            case ACTION_QUERY_STRUCTURE_ALL: {//系统管理员查询组织列表
                String creatorId = user.getUserId();
                if (isManager(creatorId) == 2) {//系统管理员
                    List<StructureInfoVO> structureAll = getStructureAll(null);
                    return gson.toJson(RetResult.successResult("查询成功", structureAll));
                } else if (isManager(creatorId) == 0) {//普通管理员
                    return queryByNoAndId(null, creatorId);
                } else {
                    return gson.toJson(RetResult.failResult("暂无权限"));
                }
            }
            case ACTION_QUERY_ONE_STRUCTURE: {//管理员查询一级组织列表
                String creatorId = user.getUserId();
                if (isManager(creatorId) == 2) {//系统管理员
                    return getOneStructure();
                } else if (isManager(creatorId) == 0) {//普通管理员
                    return queryOneLevelByNoAndId(creatorId);
                } else {
                    return gson.toJson(RetResult.failResult("暂无权限"));
                }
            }
            case ACTION_ADD_SUB_STRUCTURE: {//管理员添加下级部门
                JSONObject jsonObj = JSON.parseObject(newDataJSON);
                String creatorId = user.getUserId();
                String parentNo = jsonObj.getString("parentNo");
                //创建者名称
                String creatorName = jsonObj.getString("creatorName");
                //创建组织名称
                String structureName = jsonObj.getString("structureName");

                if (isManager(creatorId) == 1) {//系统管理员
                    return gson.toJson(RetResult.failResult("暂无权限"));
                }
                List<StructureInfoVO> vos = new ArrayList<>();
                StructureInfoVO structureInfoVO = queryStructureInfo(parentNo);
                if (structureInfoVO == null) {
                    return gson.toJson(RetResult.failResult("上级组织不存在！"));
                }
                if (Boolean.TRUE.equals(exitStructureName(parentNo, structureName))) {
                    return gson.toJson(RetResult.failResult("该组织下名称['" + structureName + "']已存在,请勿重复创建!"));
                }
                String structuresNo = ShortUuidUtil.getShortUuid();
                StructureInfoVO vo = new StructureInfoVO();
                vo.setStructureNo(structuresNo);
                vo.setStructureName(structureName);
                vo.setStructureType(0);
                vo.setCreatorName(creatorName);
                vo.setCreatorId(user.getUserId());
                vo.setStructureLevel(structureInfoVO.getStructureLevel() + ":" + structuresNo);
                vo.setParentNo(parentNo);
                vo.setRootNo(structureInfoVO.getRootNo());
                vos.add(vo);
                return addStructures(vos);
            }
            case ACTION_QUERY_SUB_STRUCTURE_ALL: {
                JSONObject jsonObj = JSON.parseObject(newDataJSON);
                String creatorId = user.getUserId();
                String parentNo = jsonObj.getString("parentNo");
                if (isManager(creatorId) == 2) {//系统管理员
                    List<StructureInfoVO> structureAll = getStructureAll(parentNo);
                    return gson.toJson(RetResult.successResult("查询成功", structureAll));
                } else if (isManager(creatorId) == 0) {//普通管理员
                    return queryByNoAndId(parentNo, creatorId);
                } else {
                    return gson.toJson(RetResult.failResult("暂无权限"));
                }
            }

            default:
                throw EndsExceptionFactory.INVALID_ACTION_ID(actionId);
        }
    }

    private String queryByNoAndId(String structureNo, String creatorId) throws Exception {
        StringBuilder builder = new StringBuilder();
        builder.append("select structure_no,structure_name,structure_level," +
                "creator_id,creator_name,parent_no,structure_type from structure_info where");
        builder.append(" creator_id = '" + creatorId + "'");
        if (EmptyUtils.isNotEmpty(structureNo)) {
            builder.append(" and structure_level like '%" + structureNo + "%'");
        }
        List<StructureInfoVO> vos = getStructureInfoVOS(builder.toString());
        if (vos.isEmpty()) {
            return gson.toJson(RetResult.successResult("查询成功", new StructureInfoVO()));
        }
        List<String> nos = vos.stream().map(StructureInfoVO::getStructureLevel).collect(Collectors.toList());
        String no = nos.stream().min(Comparator.comparing(String::length)).get();
        String[] strings = no.split(":");
        List<String> list = new ArrayList<>();
        for (String s : strings) {
            list.add(s);
        }

        List<StructureInfoVO> vos1 = queryByNos(list);
        vos.addAll(vos1);
        List<StructureInfoVO> infos = vos.stream().filter(v -> v.getParentNo().equals(v.getStructureNo())).collect(Collectors.toList());
        StructureInfoVO vo = infos.get(0);
        StructureInfoVO sv = obtainStructuresTree(vos, vo, true);
        List<StructureInfoVO> voList = new ArrayList<>();
        voList.add(sv);
        return gson.toJson(RetResult.successResult("查询成功!", voList));
    }

    /**
     * 获取组织树形结构
     *
     * @param isUser 是否包含用户
     */
    private StructureInfoVO obtainStructuresTree(List<StructureInfoVO> vos, StructureInfoVO vo, boolean isUser) throws Exception {
        List<StructureInfoVO> list = new ArrayList<>();
        for (StructureInfoVO v : vos) {
            if (v.getParentNo().equals(vo.getStructureNo())
                    && !v.getParentNo().equals(v.getStructureNo())) {
                list.add(v);
            }
        }
        vo.setChildList(list);
        if (isUser) {
            vo.setUserList(queryUserInfos(vo.getStructureNo()));
        }
        for (StructureInfoVO infoVO : vo.getChildList()) {
            obtainStructuresTree(vos, infoVO, isUser);
        }
        return vo;
    }

    private List<StructureInfoVO> queryByNos(List<String> list) throws Exception {
        String querySql = "select structure_no,structure_name,structure_level," +
                "creator_id,creator_name,parent_no,structure_type from structure_info where structure_no in ('";
        if (list.size() == 1) {
            querySql += list.get(0) + "');";
        } else {
            for (int i = 0; i < list.size() - 1; i++) {
                String s = list.get(i);
                if (i == list.size() - 2) {
                    querySql += s + "');";
                } else {
                    querySql += s + "','";
                }
            }
        }
        return getStructureInfoVOS(querySql);
    }

    private String deleteStructuresByNo(String structureNo, String creatorId) throws Exception {
        List<StructureInfoVO> vos = queryByLikeNo(structureNo, creatorId);
        if (vos.isEmpty()) {
            return gson.toJson(RetResult.failResult("组织编号不存在或你不是该组织的创建者!"));
        }

        List<String> list = new ArrayList<>();
        Vector<Vector<?>> vector = LogicProcessor2.db.queryData("select structure_no from structure_info where parent_no='" + structureNo + "'");
        Vector<Vector<?>> vector1 = LogicProcessor2.db.queryData("select structure_no from structure_user_info where structure_no='" + structureNo + "'");
        if (vector.size() <= 1 && vector1.isEmpty()) {
            list.add("delete from structure_info where structure_no='" + structureNo + "'");
        } else if (vector.size() > 1 && vector1.isEmpty()) {
            StringBuilder sql = new StringBuilder("delete from structure_info where structure_no in ('");
            for (int i = 0; i < vos.size(); i++) {
                StructureInfoVO vo = vos.get(i);
                if (i == vos.size() - 1) {
                    sql.append(vo.getStructureNo()).append("');");
                } else {
                    sql.append(vo.getStructureNo()).append("','");
                }
            }
            list.add(sql.toString());
        } else {
            StringBuilder sql = new StringBuilder("delete from structure_info where structure_no in ('");
            StringBuilder sql1 = new StringBuilder("delete from structure_user_info where structure_no in ('");
            for (int i = 0; i < vos.size(); i++) {
                StructureInfoVO vo = vos.get(i);
                if (i == vos.size() - 1) {
                    sql.append(vo.getStructureNo()).append("');");
                    sql1.append(vo.getStructureNo()).append("');");
                } else {
                    sql.append(vo.getStructureNo()).append("','");
                    sql1.append(vo.getStructureNo()).append("','");
                }
            }
            list.add(sql.toString());
            list.add(sql1.toString());
        }

        boolean update = LogicProcessor2.db.update(list, true);

        return update ? gson.toJson(RetResult.successResult("删除成功!")) : gson.toJson(RetResult.failResult("删除失败!系统异常!"));
    }

    private List<StructureInfoVO> queryByLikeNo(String structureNo, String creatorId) throws Exception {
        String querySql = "select structure_no,structure_name,structure_level," +
                "creator_id,creator_name,parent_no,structure_type from structure_info " +
                "where creator_id = '" + creatorId + "' and structure_type=0 and structure_level like '%" + structureNo + "%'";

        return getStructureInfoVOS(querySql);
    }

    private List<StructureInfoVO> getStructureInfoVOS(String querySql) throws Exception {
        Vector<Vector<?>> vectors = LogicProcessor2.db.queryData(querySql);
        List<StructureInfoVO> vos = new ArrayList<>();
        if (vectors.isEmpty()) {
            return vos;
        }

        for (Vector<?> v : vectors) {
            int i = 0;
            StructureInfoVO vo = new StructureInfoVO();
            vo.setStructureNo(v.get(i).toString());
            vo.setStructureName(v.get(++i).toString());
            vo.setStructureLevel(v.get(++i).toString());
            vo.setCreatorId(v.get(++i).toString());
            vo.setCreatorName(v.get(++i).toString());
            vo.setParentNo(v.get(++i).toString());
            vo.setStructureType(Integer.valueOf(v.get(++i).toString()));
            vos.add(vo);
        }
        return vos;
    }

    private String updateStructuresByNo(String structureNo, String creatorId, String structureName) throws Exception {
        List<StructureInfoVO> vos = queryByLikeNo(structureNo, creatorId);
        if (vos.isEmpty()) {
            return gson.toJson(RetResult.failResult("组织编号不存在或你不是该组织的创建者!"));
        }
        List<String> list = new ArrayList<>();
        String sql = "update structure_info set structure_name = '" + structureName +
                "' where structure_no = '" + structureNo + "' and structure_type=0";
        list.add(sql);
        boolean update = LogicProcessor2.db.update(list, true);

        return update ? gson.toJson(RetResult.successResult("修改成功!")) :
                gson.toJson(RetResult.failResult("修改失败!系统异常!"));
    }

    private List<StructureInfoVO> queryStructureByCreatorId(String id) throws Exception {
        String sql = "select structure_no,structure_name,structure_level," +
                "creator_id,creator_name,parent_no,structure_type from structure_info where creator_id = '" + id + "' and structure_type=0";

        return getStructureInfoVOS(sql);
    }

    private String addStructures(List<StructureInfoVO> vos) throws Exception {
        List<String> list = new ArrayList<>();
        for (StructureInfoVO vo : vos) {
            String sql = "insert into structure_info (structure_no,structure_name," +
                    "structure_level,creator_id,creator_name,parent_no,structure_type,root_no) values ('" + vo.getStructureNo() + "','" +
                    vo.getStructureName() + "','" + vo.getStructureLevel() + "','" + vo.getCreatorId() + "','" +
                    vo.getCreatorName() + "','" + vo.getParentNo() + "','" + vo.getStructureType() + "','" + vo.getRootNo() + "');";
            list.add(sql);
        }

        Boolean update = LogicProcessor2.db.update(list, true);

        return update ? gson.toJson(RetResult.successResult("添加成功!")) : gson.toJson(RetResult.failResult("添加失败!系统异常!"));
    }

    private void obtainStructures(StructureInfoVO info, List<StructureInfoVO> vos, String sb) {
        List<StructureInfoVO> childList = info.getChildList();
        if (!childList.isEmpty()) {
            for (StructureInfoVO v : childList) {
                if (CommonUtils.isStringEmpty(v.getStructureNo())) {
                    StructureInfoVO vo = new StructureInfoVO();
                    String shortUuid = ShortUuidUtil.getShortUuid();
                    vo.setStructureNo(shortUuid);
                    vo.setStructureName(v.getStructureName());
                    vo.setStructureLevel(sb + ":" + shortUuid);
                    vo.setCreatorName(v.getCreatorName());
                    vo.setCreatorId(v.getCreatorId());
                    String[] strings = sb.split(":");
                    vo.setParentNo(strings[strings.length - 1]);
                    vos.add(vo);
                    obtainStructures(v, vos, vo.getStructureLevel());
                } else {
                    obtainStructures(v, vos, sb + ":" + v.getStructureLevel());
                }
            }
        }
    }


    private Vector<Vector<?>> getUserStrure(String userId) throws Exception {
        String sql = "select structure_no,root_no,structure_level from structure_info where structure_no=(select structure_no from structure_user_info where user_id='" + userId + "') and structure_type=0";
        return LogicProcessor2.db.queryData(sql);
    }

    /**
     * 判断同一组织下  组织名称是否存在
     *
     * @param parentNo
     * @return
     */
    private Boolean exitStructureName(String parentNo, String structureName) throws Exception {
        String sql = "select * from structure_info where parent_no='" + parentNo + "' and structure_name='" + structureName + "'";
        Vector<Vector<?>> vector = LogicProcessor2.db.queryData(sql);
        return !vector.isEmpty();
    }

    /**
     * 判断是否为管理员用户
     */
    private Integer isManager(String userId) throws Exception {
        String sql = "select account_type from g_users where del_flag = 0 and user_uid='" + userId + "'";
        Vector<Vector<?>> vector = LogicProcessor2.db.queryData(sql);
        return Integer.valueOf((String) vector.get(0).get(0));
    }


    public List<StructureInfoVO> getStructureAll(String parent_no) throws Exception {
        String sql = "select structure_no,structure_name,structure_level,creator_id,creator_name," +
                "parent_no,structure_type from structure_info where structure_type=0";
        List<StructureInfoVO> structureInfoVOS = getStructureInfoVOS(sql);
        String sql1;
        if (EmptyUtils.isNotEmpty(parent_no)) {
            sql1 = sql + " and structure_no='" + parent_no + "'";
        } else {
            sql1 = sql + " and structure_no=parent_no";
        }
        List<StructureInfoVO> vos = getStructureInfoVOS(sql1);
        List<StructureInfoVO> list = new ArrayList<>();
        for (StructureInfoVO vo : vos) {
            StructureInfoVO sv = obtainStructuresTree(structureInfoVOS, vo, true);
            list.add(sv);

        }
        return list;
    }


    private List<UserInfoVO> queryUserInfos(String structureNo) throws Exception {
        String sql = "SELECT user_uid,user_mail,nickname,is_online," +
                "user_avatar_file_name,account_type,user_type FROM g_users WHERE del_flag = 0 and user_uid IN " +
                "(SELECT user_id FROM `structure_user_info`" +
                " WHERE del_flag = 0 and structure_no = '" + structureNo + "' and user_type='USER')";
        return getUserList(sql);
    }

    private List<UserInfoVO> getUserList(String sql) throws Exception {
        Vector<Vector<?>> vectors = LogicProcessor2.db.queryData(sql);
        List<UserInfoVO> vos = new ArrayList<>();
        if (!vectors.isEmpty()) {
            for (Vector<?> v : vectors) {
                int i = 0;
                UserInfoVO vo = new UserInfoVO();
                vo.setUserUid(v.get(i).toString());
                vo.setUserMail(v.get(++i).toString());
                vo.setNickname(v.get(++i).toString());
                vo.setIsOnline(Integer.valueOf(v.get(++i).toString()));
                vo.setUserAvatarFileName(v.get(++i).toString());
                vo.setAccountType(Integer.parseInt(v.get(++i).toString()));
                vo.setUserType(Integer.parseInt(v.get(++i).toString()));
                vos.add(vo);
            }
        }
        return vos;
    }

    /**
     * 系统管理员 查询一级组织列表
     */
    public String getOneStructure() throws Exception {
        String sql = "select structure_no,structure_name,structure_level,creator_id,creator_name," +
                "parent_no,structure_type from structure_info where structure_type=0 and structure_no=parent_no";
        List<StructureInfoVO> vo = getStructureInfoVOS(sql);
        return gson.toJson(RetResult.successResult("查询成功", vo));
    }

    /**
     * 普通管理员查询一级组织列表
     */
    private String queryOneLevelByNoAndId(String creatorId) throws Exception {
        String builder = "select structure_no,structure_name,structure_level," +
                "creator_id,creator_name,parent_no,structure_type from structure_info where structure_type=0 and structure_no=parent_no" +
                " and creator_id = '" + creatorId + "'";
        List<StructureInfoVO> vos = getStructureInfoVOS(builder);
        return gson.toJson(RetResult.successResult("查询成功", vos));
    }

    /**
     * 查询组织信息
     */
    public StructureInfoVO queryStructureInfo(String structureNo) throws Exception {
        String sql = "select root_no,structure_level from structure_info where structure_type=0 and structure_no='" + structureNo + "'";
        Vector<Vector<?>> vo = LogicProcessor2.db.queryData(sql);
        if (!vo.isEmpty()) {
            StructureInfoVO structureInfoVO = new StructureInfoVO();
            structureInfoVO.setRootNo(vo.get(0).get(0).toString());
            structureInfoVO.setStructureLevel(vo.get(0).get(1).toString());
            return structureInfoVO;
        }
        return null;
    }


}
